<template>
  <div class="home-page">
    <EChatHeader v-if="!$store.state.commonData.isShowChatConversation"></EChatHeader>
    <div class="chat-content" :class="!$store.state.commonData.isShowChatConversation ? 'chat-content-home' : 'chat-content-conversation'">
      <router-view></router-view>
    </div>
    <EChatNav v-if="!$store.state.commonData.isShowChatConversation"></EChatNav>
    <chat-conversation v-if="$store.state.commonData.isShowChatConversation"></chat-conversation>
    <rtc-private-video ref="rtcPrivateVideo"></rtc-private-video>
    <!--    <rtc-group-video ref="rtcGroupVideo"></rtc-group-video>-->
  </div>
</template>

<script>
import HeadImage from '../components/common/HeadImage.vue';
import Setting from '../components/setting/Setting.vue';
import UserInfo from '../components/common/UserInfo.vue';
import FullImage from '../components/common/FullImage.vue';
import RtcPrivateVideo from '../components/rtc/RtcPrivateVideo.vue';
import RtcPrivateAcceptor from '../components/rtc/RtcPrivateAcceptor.vue';
import RtcGroupVideo from '../components/rtc/RtcGroupVideo.vue';
import EChatNav from "@/components/common/EChatNav.vue";
import EChatHeader from "@/components/common/EChatHeader.vue";
import {Dialog} from "vant";
import {CryptoUtil} from "@/api/cryptoUtil";
import {bus} from '@/api/bus'
import ChatConversation from "@/view/ChatConversation.vue";

export default {
  components: {
    EChatHeader,
    EChatNav,
    HeadImage,
    Setting,
    UserInfo,
    FullImage,
    RtcPrivateVideo,
    RtcPrivateAcceptor,
    RtcGroupVideo,
    ChatConversation
  },
  data() {
    return {
      showSettingDialog: false,
      lastPlayAudioTime: new Date().getTime() - 1000,
      isFullscreen: true
    }
  },
  methods: {
    init() {
      this.$eventBus.$on('openPrivateVideo', (rctInfo) => {
        console.log('rtcInfo', rctInfo)
        this.$nextTick(() => {
          this.$refs.rtcPrivateVideo.open(rctInfo);
        })
      });
      this.$eventBus.$on('openGroupVideo', (rctInfo) => {
        // Enter multiplayer video call
        this.$refs.rtcGroupVideo.open(rctInfo);
      });

      this.$store.dispatch("load").then(() => {
        // ws init
        const protocol = window.location.protocol.includes('https') ? 'wss' : 'ws'
        const url = protocol + '://' + window.location.host + process.env.VUE_APP_WS_ROUTE
        this.$wsApi.connect(url, sessionStorage.getItem("accessToken"));
        // const protocol = window.location.protocol.includes('https') ? 'wss' : 'ws'
        // this.$wsApi.connect(protocol + '://'+window.location.host+'/im', sessionStorage.getItem("accessToken"));
        this.$wsApi.onConnect(() => {
          // Load offline messages
          this.pullPrivateOfflineMessage(this.$store.state.chatStore.privateMsgMaxId);
          this.pullGroupOfflineMessage(this.$store.state.chatStore.groupMsgMaxId);
        });
        this.$wsApi.onMessage((cmd, msgInfo) => {
          if (cmd == 2) {
            // close ws
            this.$wsApi.close(3000)
            // Remote login, forced offline
            // before this.$alert
            Dialog.alert({
              title: 'Mandatory offline notification',
              message: 'You have logged in elsewhere and will be forced to log out',
              confirmButtonColor: 'var(--chat-theme-color)',
              confirmButtonText: 'Confirm',
              cancelButtonText: 'Cancel',
            }).then(() => {
              location.href = "/";
            });
          } else if (cmd == 3) {
            // Insert private message
            this.handlePrivateMessage(msgInfo);
            console.log('------------msgInfo', msgInfo)
          } else if (cmd == 4) {
            // Insert group chat message
            this.handleGroupMessage(msgInfo);
          } else if (cmd == 5) {
            // Process system messages
            this.handleSystemMessage(msgInfo);
          }
        });
        this.$wsApi.onClose((e) => {
          console.log(e);
          if (e.code != 3000) {
            this.$message.error("Connection disconnected, attempting to reconnect...");
            this.$wsApi.reconnect(url, sessionStorage.getItem("accessToken"));

            // const protocol = window.location.protocol.includes('https') ? 'wss' : 'ws'
            // const url = protocol + '://' + window.location.host + process.env.VUE_APP_WS_ROUTE
            // this.$wsApi.reconnect(url, sessionStorage.getItem("accessToken"));
          }
        });
      }).catch((e) => {
        console.log("Init error", e);
      })
    },
    pullPrivateOfflineMessage(minId) {
      this.$store.commit("loadingPrivateMsg", true)
      this.$http({
        url: "/message/private/pullOfflineMessage",
        method: 'POST',
        params: {
          minId: minId
        }
      }).catch(() => {
        this.$store.commit("loadingPrivateMsg", false)
      })
    },
    pullGroupOfflineMessage(minId) {
      this.$store.commit("loadingGroupMsg", true)
      this.$http({
        url: "/message/group/pullOfflineMessage",
        method: 'POST',
        params: {
          minId: minId
        }
      }).catch(() => {
        this.$store.commit("loadingGroupMsg", false)
      })
    },
    handlePrivateMessage(msg) {
      console.log('handlePrivateMessage', msg)
      // Message loading flag
      if (msg.type == this.$enums.MESSAGE_TYPE.LOADING) {
        this.$store.commit("loadingPrivateMsg", JSON.parse(msg.content))
        return;
      }
      // Message read processing, clear read quantity
      if (msg.type == this.$enums.MESSAGE_TYPE.READED) {
        this.$store.commit("resetUnreadCount", {
          type: 'PRIVATE',
          targetId: msg.recvId
        })
        return;
      }
      // Message receipt processing, change the message status to read
      if (msg.type == this.$enums.MESSAGE_TYPE.RECEIPT) {
        this.$store.commit("readedMessage", {
          friendId: msg.sendId
        })
        return;
      }
      // Mark if this message was sent by yourself
      msg.selfSend = msg.sendId == this.$store.state.userStore.userInfo.id;
      // single webrtc
      if (this.$msgType.isRtcPrivate(msg.type)) {
        this.$refs.rtcPrivateVideo.onRTCMessage(msg)
        return;
      }
      let friendId = msg.selfSend ? msg.recvId : msg.sendId;
      this.loadFriendInfo(friendId).then((friend) => {
        this.insertPrivateMessage(friend, msg);
      })
    },
    insertPrivateMessage(friend, msg) {
      console.log('insertPrivateMessage', friend, msg)

      let chatInfo = {
        type: 'PRIVATE',
        targetId: friend.id,
        showName: friend.nickName,
        headImage: friend.headImage
      };
      this.$store.commit("openChat", chatInfo);
      this.$store.commit("insertMessage", msg);
      // Play prompt sound
      if (!msg.selfSend && this.$msgType.isNormal(msg.type) &&
          msg.status != this.$enums.MESSAGE_STATUS.READED) {
        this.playAudioTip();
      }
    },
    handleGroupMessage(msg) {
      // Message loading flag
      if (msg.type == this.$enums.MESSAGE_TYPE.LOADING) {
        this.$store.commit("loadingGroupMsg", JSON.parse(msg.content))
        return;
      }
      // Message read and processed
      if (msg.type == this.$enums.MESSAGE_TYPE.READED) {
        // I have read the other party's message and cleared the read quantity
        let chatInfo = {
          type: 'GROUP',
          targetId: msg.groupId
        }
        this.$store.commit("resetUnreadCount", chatInfo)
        return;
      }
      // Message receipt processing
      if (msg.type == this.$enums.MESSAGE_TYPE.RECEIPT) {
        // Update the number of people who have read the message
        let msgInfo = {
          id: msg.id,
          groupId: msg.groupId,
          readedCount: msg.readedCount,
          receiptOk: msg.receiptOk
        };
        this.$store.commit("updateMessage", msgInfo)
        return;
      }
      // Mark if this message was sent by yourself
      msg.selfSend = msg.sendId == this.$store.state.userStore.userInfo.id;
      // Group video signaling
      if (this.$msgType.isRtcGroup(msg.type)) {
        this.$nextTick(() => {
          this.$refs.rtcGroupVideo.onRTCMessage(msg);
        })
        return;
      }
      this.loadGroupInfo(msg.groupId).then((group) => {
        this.insertGroupMessage(group, msg);
      })
    },
    insertGroupMessage(group, msg) {
      let chatInfo = {
        type: 'GROUP',
        targetId: group.id,
        showName: group.remarkGroupName,
        headImage: group.headImageThumb
      };
      this.$store.commit("openChat", chatInfo);
      this.$store.commit("insertMessage", msg);
      if (!msg.selfSend && msg.type <= this.$enums.MESSAGE_TYPE.VIDEO &&
          msg.status != this.$enums.MESSAGE_STATUS.READED) {
        this.playAudioTip();
      }
    },
    handleSystemMessage(msg) {
      // User banned
      if (msg.type == this.$enums.MESSAGE_TYPE.USER_BANNED) {
        this.$wsApi.close(3000);
        Dialog.alert({
          title: 'Account banned',
          message: 'Your account has been banned by the administrator, reason::' + msg.content,
          confirmButtonColor: 'var(--chat-theme-color)',
          confirmButtonText: 'Confirm',
          cancelButtonText: 'Cancel',
        }).then(() => {
          this.onExit();
        });

        return;
      }
    },
    onExit() {
      this.$wsApi.close(3000);
      sessionStorage.removeItem("accessToken");
      location.href = "/";
    },
    playAudioTip() {
      // Offline messages do not play ringtones
      if (this.$store.getters.isLoading()) {
        return;
      }
      // Prevent overly dense playback
      if (new Date().getTime() - this.lastPlayAudioTime > 1000) {
        this.lastPlayAudioTime = new Date().getTime();
        let audio = new Audio();
        let url = require(`@/assets/audio/tip.wav`);
        audio.src = url;
        audio.play();
      }

    },
    showSetting() {
      this.showSettingDialog = true;
    },
    closeSetting() {
      this.showSettingDialog = false;
    },
    loadFriendInfo(id) {
      return new Promise((resolve, reject) => {
        let friend = this.$store.state.friendStore.friends.find((f) => f.id == id);
        if (friend) {
          resolve(friend);
        } else {
          this.$http({
            url: `/friend/find`,
            method: 'POST',
            params: {
              friendId: id
            }
          }).then((friend) => {
            this.$store.commit("addFriend", friend);
            resolve(friend)
          })
        }
      });
    },
    loadGroupInfo(id) {
      return new Promise((resolve, reject) => {
        let group = this.$store.state.groupStore.groups.find((g) => g.id == id);
        if (group) {
          resolve(group);
        } else {
          this.$http({
            url: "/group/find",
            method: 'POST',
            params: {
              groupId: id
            }
          }).then((group) => {
            resolve(group)
            this.$store.commit("addGroup", group);
          })
        }
      });
    }
  },
  computed: {
    chatStore() {
      return this.$store.state.chatStore;
    },
    uiStore() {
      return this.$store.state.uiStore;
    },
    unreadCount() {
      let unreadCount = 0;
      let chats = this.$store.state.chatStore.chats;
      chats.forEach((chat) => {
        if (!chat.delete) {
          unreadCount += chat.unreadCount
        }
      });
      return unreadCount;
    }
  },
  watch: {
    unreadCount: {
      handler(newCount, oldCount) {
        let tip = newCount > 0 ? `${newCount} unread ${newCount > 1 ? "items" : "item"}` : "";
        this.$elm.setTitleTip(tip);
      },
      immediate: true
    }
  },
  mounted() {
    this.init();
    let recaptchaScript = document.createElement('script')
    recaptchaScript.setAttribute('src', '/zip-full.min.js')
    document.head.appendChild(recaptchaScript)

    var code = Number(sessionStorage.getItem("code"));
    this.$store.dispatch("loadEncryption", code)
  },
  unmounted() {
    this.$wsApi.close();
  }
}
</script>

<style scoped lang="scss">
.home-page {
  .chat-content {
    width: 100%;
    flex: 1;
    background: var(--chat-content-bg);
    //overflow-y: auto;
  }
  background: var(--chat-content-bg);
}

.chat-content-home {
  min-height: calc(100vh - 210px);
  overflow-y: auto;
  transform: translate(0, 110px);
}

.chat-content-conversation {
  height: 0;
  transform: translate(0, 0);
}

</style>